package com.damai.aop.impl;

import java.lang.reflect.Method;

import com.damai.aop.MethodCaller;
import com.damai.aop.MethodInterceptor;
import com.damai.aop.MethodInvoker;

public class MethodInvokerImpl implements MethodInvoker {
	private Object returnValue;
	private Object[] args;
	private Object target;
	
	private int index ;
	private MethodInterceptor[] interceptors;
	private Method method;
	private MethodCaller caller;
	
	public MethodInvokerImpl(MethodInfo info, Object target,  Object[] args){
		this.interceptors = info.interceptors;
		this.caller = info.caller;
		this.target = target;
		this.args = args;
		this.method = info.method;
	}
	
	@Override
	public void invoke() {
		if(index < interceptors.length ){
			interceptors[index++].intercept(this);
		}else{
			if(index ++ == interceptors.length){
				returnValue = caller.call(target, args);
			}
		}
		
	}

	@Override
	public Object getReturnValue() {
		return returnValue;
	}

	@Override
	public Object[] getArgs() {
		return args;
	}

	@SuppressWarnings("unchecked")
	@Override
	public <T> T getTarget() {
		return (T)target;
	}


	@Override
	public void setArg(int index, Object arg) {
		if(index <0 || index >= this.args.length){
			return;
		}
		this.args[index] = arg;
	}


	@Override
	public void setArgs(Object[] args) {
		this.args = args;
	}


	@Override
	public void setReturnValue(Object returnValue) {
		this.returnValue = returnValue;
	}


	@Override
	public Method getMethod() {
		return method;
	}

}
